package com.yifeng.repo.base.utils.file;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * copy from FileHandler of tomcat 8.5.54
 */
public class FileCleanHelper {

    public static void clean(String logPath, int maxDays, String prefix, String suffix) {
        if (maxDays <= 0) {
            return;
        }
        try (DirectoryStream<Path> files = streamFilesForDelete(logPath, maxDays, prefix, suffix)){
            for (Path file : files) {
                Files.delete(file);
            }
        } catch (IOException e) {
            System.err.println("Unable to delete log files older than " + maxDays + ", error: " + e.getMessage());
        }
    }

    private static DirectoryStream<Path> streamFilesForDelete(String logPath, int maxDays, String prefix, String suffix) throws IOException {
        final Date maxDaysOffset = getMaxDaysOffset(maxDays);
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return Files.newDirectoryStream(new File(logPath).toPath(),
                new DirectoryStream.Filter<Path>() {
                    @Override
                    public boolean accept(Path path) throws IOException {
                        boolean result = false;
                        String date = obtainDateFromPath(path, prefix, suffix);
                        if (date != null) {
                            try {
                                Date dateFromFile = formatter.parse(date);
                                result = dateFromFile.before(maxDaysOffset);
                            } catch (ParseException e) {
                                // no-op
                            }
                        }
                        return result;
                    }
                });
    }

    private static String obtainDateFromPath(Path path, String prefix, String suffix) {
        // Represents a file name pattern of type {prefix}{date}{suffix}. The date is YYYY-MM-DD
        Pattern pattern = Pattern.compile("^(" + Pattern.quote(prefix) + ")\\d{4}-\\d{1,2}-\\d{1,2}(" + Pattern.quote(suffix) + ")$");;
        Path fileName = path.getFileName();
        if (fileName == null) {
            return null;
        }
        String date = fileName.toString();
        if (pattern.matcher(date).matches()) {
            date = date.substring(prefix.length());
            return date.substring(0, date.length() - suffix.length());
        } else {
            return null;
        }
    }

    private static Date getMaxDaysOffset(int maxDays) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DATE, -maxDays);
        return cal.getTime();
    }

    public static void main(String[] args) throws Exception {
        System.out.println("start to do...");
        String logPath = "/Users/daibing/Downloads/logs";
        FileCleanHelper.clean(logPath, 3, "fire-drm-daemon-stderr.", ".log");
//        FileCleanHelper.clean(logPath, 3, "fire-drm-daemon-service.", ".log");
        System.out.println("success.");
    }
}
